package com.example.demo.thread;

import java.util.concurrent.*;

public class threadTest {
    /**
     * 1. 继承Thread
     * Thread01 thread01 = new Thread01();
     * thread01.start();
     * <p>
     * 2. 实现Runnable接口
     * Runnable01 runnable01 = new Runnable01();
     * new Thread(runnable01).start()
     * <p>
     * 3. 实现Callable接口，+FuturTask（可以拿到返回结果，可以处理异常）
     * FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
     * new Thread(futureTask).start();
     * Integer integer = futureTask.get();
     * System.out.println("返回结果是"+integer);
     * 4. 线程池
     * 创建方式
     * ----- ExecutorService
     */

    /**
     * 线程池7大参数
     * int corePoolSize,核心线程池，创建好就准备就绪的线程数量，等待来接受异步任务去执行
     * int maximumPoolSize,最大线程数量，控制资源
     * long keepAliveTime,存活时间：线程空闲大于存活的时间，会释放空闲的线程。
     * TimeUnit unit,
     * BlockingQueue<Runnable> workQueue,阻塞队列，如果任务有很多，就会将目前多的任务放入队列里面，只要有空闲线程，就回去队列里面取出新的任务继续
     * ThreadFactory threadFactory,
     * RejectedExecutionHandler handler。队列满了，按照指定的拒绝策略拒绝执行任务。
     */

    /**
     * 运行流程
     * 1 线程池创建，准备好core的核心线程，准备接受任务
     * 2 新的任务进来，用core准备好的空闲线程执行
     * 2.1 core满了，就将在进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行
     * 2.2 阻塞队列满了，就直接开新线程执行，最大只能开到max指定的任务
     * 2.3 max都执行好了，max-core数量空闲的线程会在keepAliveTime指定的时间后自动销毁，最终保持到core的大小
     * 2.4 如果线程开到了max的数量，还有新任务进来，就会用reject指定的拒绝策略进行处理
     * 3 所有的线程创建都是由指定的factory创建。
     */
    static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        System.out.println("main start");

        //当前系统中池只有1两个个，每个异步任务，提交给线程池
        //pool.execute(new Runnable01());
        //CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        //    System.out.println("当前线程：" + Thread.currentThread().getId());
        //    int i = 10 / 2;
        //    System.out.println("运行结果是：" + i);
        //}, executor);

      /*  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果是：" + i);
            return i;
        }, executor).whenComplete((t, u) -> {
            //虽然能得到异常，但是无法修改结果
            System.out.println("异步任务成功完成了， 结果是" + t + " ;异常是" + u);
        }).exceptionally(throwable -> {
            //可以感知异常，同时返回 默认值
            return 10;
        });*/

        /*  方法执行完后的处理  */
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果是：" + i);
            return i;
        }, executor).handle((res,thr)->{
            if (res!=null){
                return res*2;
            }
            if(thr!=null){
                return 0;
            }
            return 0;
        });
        Integer integer = future.get();
        System.out.println("result is :" + integer);

        System.out.println("main end");
    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果是：" + i);
        }
    }

    public static class Runnable01 implements Runnable {

        @Override
        public void run() {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果是：" + i);
        }
    }

    public static class Callable01 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果是：" + i);
            return i;
        }
    }
}
